/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.playground.core.repository.memory;

import com.playground.core.entity.Room;
import com.playground.core.entity.RoomStatus;
import com.playground.core.repository.RoomRepository;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import org.springframework.stereotype.Service;

/**
 *
 * @author Tiago Peres
 */
@Service("roomRepository")
public class RoomRepositoryImpl implements RoomRepository {
    private static HashMap<Long, Room> rooms = new HashMap<Long, Room>();
    private static HashMap<Long, RoomStatus> oldStatus = new HashMap<Long, RoomStatus>();
    private static EnumMap<RoomStatus, List<Room>> statusIndex = new EnumMap<RoomStatus, List<Room>>(RoomStatus.class);
    private static long nextId = 1;
    
    public RoomRepositoryImpl(){
        for(RoomStatus status : RoomStatus.values()){
            statusIndex.put(status, new ArrayList());
        }
    }

    public synchronized Room save(Room room) {
        if (room.getId() == -1){
            System.out.println("+++ Adding new room...");
            Room r = new Room(nextId);
            r.setMaxPlayers(room.getMaxPlayers());
            r.setStatus(room.getStatus());
            r.setGameTitle(room.getGameTitle());
            r.setPlayers(room.getPlayers());
            rooms.put(nextId, r);
            oldStatus.put(nextId, r.getStatus());
            statusIndex.get(r.getStatus()).add(r);
            nextId++;
            return r;
        }
        // if the room status has changed, update the index
        RoomStatus pastStatus = oldStatus.get(room.getId());
        System.out.println("+++++++++++++++++++++++++++++++++++");
        System.out.println(pastStatus);
        System.out.println(room.getStatus());
        if (!pastStatus.equals(room.getStatus())){
            System.out.println("Changed");
            System.out.println(statusIndex.get(pastStatus).size());
            statusIndex.get(pastStatus).remove(room);
            System.out.println(statusIndex.get(pastStatus).size());
            statusIndex.get(room.getStatus()).add(room);
            oldStatus.put(room.getId(), room.getStatus());
        }
        return room;
    }

    public synchronized Room findOne(long id) {
        return rooms.get(id);
    }

    // CLONING THIS LIST WON'T CAUSE PERFORMANCE ISSUES? Not cloning causes conccurence problems.
    public synchronized List<Room> findRoomByStatus(RoomStatus status) {
        return (List<Room>)(((ArrayList) statusIndex.get(status)).clone());
    }

    public synchronized List<Room> findAll() {
        return new ArrayList(rooms.values());
    }

    public synchronized void deleteAll() {
        rooms = new HashMap<Long, Room>();
        oldStatus = new HashMap<Long, RoomStatus>();
        for(RoomStatus status : RoomStatus.values()){
            statusIndex.put(status, new ArrayList());
        }
    }
    
}
